#pragma once
#include "base/core/os/os_head.h"
#include <stdint.h>
#include "base/core/os/string.h"
#include "base/net/net.h"

#if defined(WIN32)
#define ERR_INTER       WSAEINTR
#define ERR_EAGAIN      WSAEWOULDBLOCK
#define ERR_INPROGRESS  WSAEINPROGRESS
#define SHUTDOWN_RECV   SD_RECEIVE
#define SHUTDOWN_SEND   SD_SEND
#define SHUTDOWN_BOTH   SD_BOTH
#else  // defined(OS_LINUX)

#include <sys/socket.h>
#include <sys/types.h>
#include<netinet/in.h> 

#define ERR_INTER       EINTR
#define ERR_EAGAIN      EAGAIN
#define ERR_INPROGRESS  EINPROGRESS
#define SHUTDOWN_RECV   SHUT_RD
#define SHUTDOWN_SEND   SHUT_WR
#define SHUTDOWN_BOTH   SHUT_RDWR
#endif  // OS


class Socket 
{
public:
	static int    GetSocketError();  
	static char*  GetSocketErrorMsg(int err_no, char *buf, size_t len);
	static SOCKET Create(int nodelay_flag = 1);
	static bool   Close(SOCKET sock);
	static bool   Shutdown(SOCKET sock, int how);
	static bool   SetReuse(SOCKET sock);
	static bool   SetNonBlock(SOCKET sock);
	static bool   SetNoDelay(SOCKET sock, int flag = 1);
	static int    Accept(SOCKET listen_sock, SOCKET* sock);
	static bool   Connect(SOCKET sock, const char* ip, uint16_t port);
	static bool   Listen(SOCKET sock, const char* ip, uint16_t port);
	static int    Send(SOCKET sock, const char* buf, uint32_t len);
	static int    Recv(SOCKET sock, char* buf, uint32_t size);
	static bool   GetPeerAddress(SOCKET sock, char* IPBuffer, uint32_t IPBufferSize, uint16_t* port);
	static int    IpStrToInt(const char* ip);
	static int    TpIntToStr(int ip, std::string* ip_str);
	static bool   GetMac(char* mac);

protected:
	Socket();
	virtual ~Socket();
};